#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <pthread.h>
#include "shmem.h"  // 引入共享内存头文件
#include "msg_queue.h"
#include <errno.h>      // 提供errno的定义
#include <signal.h>     // 提供EINTR的定义

#define PORT 8888                  // TCP服务器端口（接收单片机）
#define TCP_SERVER_IP "172.26.107.87"  // TCP服务器监听的IP地址
#define QT_TCP_PORT 9999           // QT的TCP服务端端口
#define QT_TCP_IP "172.26.107.87"      // QT的TCP服务端IP（默认）
#define BUFFER_SIZE 4096           // 缓冲区大小
#define MAX_CLIENTS 10             // 最大客户端数量

// 客户端信息结构体（单片机）
typedef struct {
    int socket;
    struct sockaddr_in address;     // 存储单片机IP和端口
    pthread_t thread;
    int active;
} Client;

// 全局变量
Client clients[MAX_CLIENTS];
pthread_mutex_t clients_mutex = PTHREAD_MUTEX_INITIALIZER;
int server_socket;                 // 接收单片机的TCP套接字
int qt_tcp_socket = -1;            // 连接QT的TCP套接字
struct shmem_param shmem_info;     // 共享内存信息
pthread_mutex_t qt_mutex = PTHREAD_MUTEX_INITIALIZER;  // QT连接互斥锁
int msg_queue_id = -1;  // 消息队列ID，初始化后有效
void send_message_to_client(int client_index, const char* message);

// 存储QT的TCP地址（全局变量，支持动态修改）
char qt_target_ip[INET_ADDRSTRLEN] = QT_TCP_IP;
int qt_target_port = QT_TCP_PORT;

// 连接到QT的TCP服务端
int connect_to_qt_tcp() {
    pthread_mutex_lock(&qt_mutex);
    
    // 关闭现有连接
    if (qt_tcp_socket != -1) {
        close(qt_tcp_socket);
        qt_tcp_socket = -1;
    }

    // 创建套接字
    int sock = socket(AF_INET, SOCK_STREAM, 0);
    if (sock == -1) {
        perror("Failed to create QT TCP socket");
        pthread_mutex_unlock(&qt_mutex);
        return -1;
    }

    // 设置QT地址
    struct sockaddr_in qt_addr;
    memset(&qt_addr, 0, sizeof(qt_addr));
    qt_addr.sin_family = AF_INET;
    qt_addr.sin_port = htons(qt_target_port);
    if (inet_pton(AF_INET, qt_target_ip, &qt_addr.sin_addr) <= 0) {
        perror("Invalid QT TCP IP address");
        close(sock);
        pthread_mutex_unlock(&qt_mutex);
        return -1;
    }

    // 连接QT
    if (connect(sock, (struct sockaddr*)&qt_addr, sizeof(qt_addr)) == -1) {
        perror("Failed to connect to QT TCP server");
        close(sock);
        pthread_mutex_unlock(&qt_mutex);
        return -1;
    }

    qt_tcp_socket = sock;
    printf("Connected to QT TCP server: %s:%d\n", qt_target_ip, qt_target_port);
    pthread_mutex_unlock(&qt_mutex);
    return 0;
}

// 发送IP和端口到QT（每次调用都发送，不限制次数）
void send_ip_port_to_qt(const char* ip, int port) {
    pthread_mutex_lock(&qt_mutex);
    
    // 检查连接，断开则重连
    if (qt_tcp_socket == -1) {
        if (connect_to_qt_tcp() != 0) {
            printf("Failed to send IP:Port to QT (not connected)\n");
            pthread_mutex_unlock(&qt_mutex);
            return;
        }
    }

    // 格式化IP和端口（仅包含这两个信息）
    char qt_data[BUFFER_SIZE];
    snprintf(qt_data, BUFFER_SIZE, "%s:%d", ip, port);  // 格式："IP:端口"

    // 发送到QT
    if (send(qt_tcp_socket, qt_data, strlen(qt_data), 0) == -1) {
        perror("Failed to send IP:Port to QT");
        close(qt_tcp_socket);  // 发送失败，下次重连
        qt_tcp_socket = -1;
    } else {
        printf("Sent to QT TCP: %s (IP:Port)\n", qt_data);
    }
    
    pthread_mutex_unlock(&qt_mutex);
}

// 处理单片机客户端
void* handle_client(void* arg) {
    int client_index = *(int*)arg;
    Client* client = &clients[client_index];
    char buffer[BUFFER_SIZE];

    // 获取单片机IP和端口（连接时保存，后续每次发送数据都用这个）
    char client_ip[INET_ADDRSTRLEN];
    inet_ntop(AF_INET, &(client->address.sin_addr), client_ip, INET_ADDRSTRLEN);
    int client_port = ntohs(client->address.sin_port);  // 转换为本地字节序
    printf("Client %d (MCU) connected: %s:%d\n", client_index, client_ip, client_port);

    // 接收单片机数据（每次接收都触发QT发送）
    ssize_t recv_len;
    while ((recv_len = recv(client->socket, buffer, BUFFER_SIZE - 1, 0)) > 0) {
        buffer[recv_len] = '\0';
        printf("From MCU %d: %s\n", client_index, buffer);  // 打印数据

        // 写入共享内存（保留原有功能）
        shmem_write(&shmem_info, buffer, recv_len);

        // 核心修改：每次接收数据都发送IP和端口给QT（重复发送）
        send_ip_port_to_qt(client_ip, client_port);
    }

    // 客户端断开连接
    printf("Client %d (MCU) disconnected\n", client_index);
    close(client->socket);
    
    pthread_mutex_lock(&clients_mutex);
    client->active = 0;
    pthread_mutex_unlock(&clients_mutex);

    pthread_exit(NULL);
}
void* handle_msg_to_mcu(void* arg) {
    struct Msg msg_buf;  // 消息缓冲区
    ssize_t recv_len;    // 接收的消息长度

    printf("handle_msg_to_mcu thread started, waiting for messages...\n");

    while (1) {
        // 从消息队列读取消息（阻塞模式）
        recv_len = msg_queue_recv(
            msg_queue_id,
            &msg_buf,
            sizeof(msg_buf.buf),  // 消息正文大小
            0,                    // 接收任何类型的消息
            0                     // 阻塞等待
        );

        // 处理接收错误
        if (recv_len == -1) {
            if (errno == EINTR) {
                // 系统调用被信号中断，继续接收
                continue;
            }
            perror("Failed to receive message from queue");
            sleep(1);  // 避免CPU占用过高
            continue;
        }

        // 打印接收到的消息
        printf("Received broadcast message: %.*s\n", (int)recv_len, msg_buf.buf);

        // 加锁遍历所有客户端
        pthread_mutex_lock(&clients_mutex);
        
        for (int i = 0; i < MAX_CLIENTS; i++) {
            if (clients[i].active) {
                // 发送消息到活跃客户端
                ssize_t send_len = send(
                    clients[i].socket,
                    msg_buf.buf,
                    recv_len,  // 发送原始消息长度
                    0
                );

                if (send_len == -1) {
                    perror("Failed to send message to client");
                    // 标记客户端为非活跃（可选，取决于应用需求）
                    // clients[i].active = 0;
                } else {
                    printf("Broadcast to client %d: %.*s\n", i, (int)send_len, msg_buf.buf);
                }
            }
        }

        pthread_mutex_unlock(&clients_mutex);
    }

    // 理论上不会执行到这里
    pthread_exit(NULL);
    return NULL;
}
// 发送消息给单片机客户端
void send_message_to_client(int client_index, const char* message) {
    pthread_mutex_lock(&clients_mutex);
    if (client_index >= 0 && client_index < MAX_CLIENTS && clients[client_index].active) {
        send(clients[client_index].socket, message, strlen(message), 0);
        printf("Sent to MCU %d: %s\n", client_index, message);
    } else {
        printf("Error: MCU client %d not available\n", client_index);
    }
    pthread_mutex_unlock(&clients_mutex);
}

// 处理用户输入
void* handle_user_input(void* arg) {
    char command[BUFFER_SIZE];
    int client_index, new_port;
    char message[BUFFER_SIZE], new_ip[INET_ADDRSTRLEN];

    while (1) {
        printf("Enter command (s <client_index> <message> | qt <ip> <port> | q to quit): ");
        fgets(command, BUFFER_SIZE, stdin);
        
        // 解析命令
        if (strncmp(command, "s ", 2) == 0) {
            // 发送消息给单片机
            sscanf(command, "s %d %[^\n]", &client_index, message);
            send_message_to_client(client_index, message);
        } else if (strncmp(command, "qt ", 3) == 0) {
            // 修改QT地址并重新连接
            sscanf(command, "qt %15s %d", new_ip, &new_port);
            strncpy(qt_target_ip, new_ip, INET_ADDRSTRLEN);
            qt_target_port = new_port;
            printf("Updated QT TCP target to %s:%d, reconnecting...\n", qt_target_ip, qt_target_port);
            connect_to_qt_tcp();  // 立即重连
        } else if (strncmp(command, "q", 1) == 0) {
            // 退出服务器
            printf("Shutting down server...\n");
            close(server_socket);
            pthread_mutex_lock(&qt_mutex);
            if (qt_tcp_socket != -1) close(qt_tcp_socket);
            pthread_mutex_unlock(&qt_mutex);
            pthread_exit(NULL);
        }
    }
}

int main() {
    // 初始化客户端数组
    for (int i = 0; i < MAX_CLIENTS; i++) {
        clients[i].active = 0;
    }

    // 初始化共享内存
    if (shmem_init(&shmem_info, SHMEM_NAME, BUFFER_SIZE) != 0) {
        perror("Shared memory initialization failed");
        return EXIT_FAILURE;
    }
    printf("shmem [id = %d]\n", shmem_info.id);

    


    // 创建接收单片机的TCP套接字
    server_socket = socket(AF_INET, SOCK_STREAM, 0);
    if (server_socket == -1) {
        perror("socket creation failed");
        shmem_del(&shmem_info);
        return EXIT_FAILURE;
    }
    // 初始化消息队列
    msg_queue_id = msg_queue_init(MSG_QUEUE_NAME);
    printf("[msg_queue_id = %d]\n", msg_queue_id);
    if (msg_queue_id != -1) {
        pthread_t msg_thread;
        if (pthread_create(&msg_thread, NULL, handle_msg_to_mcu, NULL) != 0) {
            perror("Failed to create msg queue thread");
        } else {
            pthread_detach(msg_thread);
            printf("Message queue -> MCU thread started\n");
        }
    }

    // 配置服务器地址
    struct sockaddr_in server_addr;
    memset(&server_addr, 0, sizeof(server_addr));
    server_addr.sin_family = AF_INET;
    server_addr.sin_addr.s_addr = inet_addr(TCP_SERVER_IP);  // 服务器IP
    server_addr.sin_port = htons(PORT);

    // 绑定并监听
    if (bind(server_socket, (struct sockaddr*)&server_addr, sizeof(server_addr)) == -1) {
        perror("bind failed");
        close(server_socket);
        shmem_del(&shmem_info);
        return EXIT_FAILURE;
    }
    if (listen(server_socket, MAX_CLIENTS) == -1) {
        perror("listen failed");
        close(server_socket);
        shmem_del(&shmem_info);
        return EXIT_FAILURE;
    }

    printf("Server listening for MCU on %s:%d...\n", 
           inet_ntoa(server_addr.sin_addr), ntohs(server_addr.sin_port));

    // 初始连接QT
    if (connect_to_qt_tcp() != 0) {
        printf("Warning: Initial QT connection failed (will retry later)\n");
    }

    // 创建用户输入线程
    pthread_t input_thread;
    pthread_create(&input_thread, NULL, handle_user_input, NULL);

// 新增：创建消息队列→单片机转发线程（仅当消息队列初始化成功时）
    if (msg_queue_id != -1) {
        pthread_t msg_thread;
        if (pthread_create(&msg_thread, NULL, handle_msg_to_mcu, NULL) != 0) {
            perror("Failed to create msg queue thread");
        } else {
            pthread_detach(msg_thread);  // 分离线程，自动回收资源
            printf("Message queue -> MCU thread started\n");
        }
    }

    // 接受客户端连接
    while (1) {
        struct sockaddr_in client_addr;
        socklen_t client_addr_len = sizeof(client_addr);
        int client_socket = accept(server_socket, (struct sockaddr*)&client_addr, &client_addr_len);
        
        if (client_socket == -1) {
            if (server_socket == -1) break;  // 服务器关闭
            perror("accept failed");
            continue;
        }

        // 分配客户端槽位
        int client_index = -1;
        pthread_mutex_lock(&clients_mutex);
        for (int i = 0; i < MAX_CLIENTS; i++) {
            if (!clients[i].active) {
                client_index = i;
                clients[i].socket = client_socket;
                clients[i].address = client_addr;
                clients[i].active = 1;
                break;
            }
        }
        pthread_mutex_unlock(&clients_mutex);

        if (client_index != -1) {
            pthread_create(&clients[client_index].thread, NULL, handle_client, &client_index);
            pthread_detach(clients[client_index].thread);
        } else {
            char* msg = "Server is full";
            send(client_socket, msg, strlen(msg), 0);
            close(client_socket);
        }
    }
// 新增：创建消息队列→单片机转发线程（仅当消息队列初始化成功时）
    if (msg_queue_id != -1) {
        pthread_t msg_thread;
        if (pthread_create(&msg_thread, NULL, handle_msg_to_mcu, NULL) != 0) {
            perror("Failed to create msg queue thread");
        } else {
            pthread_detach(msg_thread);  // 分离线程，自动回收资源
            printf("Message queue -> MCU thread started\n");
        }
    }

    // 清理资源
    pthread_join(input_thread, NULL);
    for (int i = 0; i < MAX_CLIENTS; i++) {
        if (clients[i].active) close(clients[i].socket);
    }
    pthread_mutex_destroy(&clients_mutex);
    pthread_mutex_destroy(&qt_mutex);
    shmem_del(&shmem_info);

    return 0;
}